﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace PixelWarfare
{
    /// <summary>
    /// Creates a screen to show the score table at the end of each game.
    /// </summary>
    class ScoreScreen : Menu
    {
        #region Fields

        private static ScoreScreen theOne;  // Singleton instance.
        private Game game;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new ScoreScreen, 
        /// </summary>
        private ScoreScreen()
            : base()
        {
            game = Game.GetInstance();

            AddSelectionItem("QUIT", 150, 450, new Font("Arial", 30), Color.White, Color.Gray,
                new OnClick(ToMainMenu));

            AddSelectionItem("NEXT", 350, 450, new Font("Arial", 30), Color.White, Color.Gray,
                new OnClick(NewGame));
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets the singleton instance of the class.
        /// </summary>
        /// <returns>Return the singleton instance.</returns>
        public static ScoreScreen GetInstance()
        {
            // Create it if it doesnt already exist.
            if (theOne == null)
            {
                theOne = new ScoreScreen();
            }

            /* Since were using it as a singleton we need to update it
             * as unexpired everytime we want to show it again. 
             * Otherwise the screen would switch immediately. */
            theOne.ValidateScreen();

            return theOne;
        }

        /// <summary>
        /// Draws the score table and the selection items underneath.
        /// </summary>
        /// <param name="g">Graphics to be drawn on.</param>
        public override void Draw(Graphics g)
        {
            base.Draw(g);

            int xOffset = -210;                 // XOffset as you draw the column headings.
            int yOffset = -150;                 // Need to keep track of the yOffset through all the rows.       
            
            Font font = new Font("arial", 20);
            string text;

            // Draw the main heading.
            Utility.DrawTextCentered(g, "RESULTS", Color.White, -200, 0, 40);

            // Draw the column headings.
            for (int i = 0; i < Game.TurnsPerPlayer + 2; i++)
            {
                if (i < Game.TurnsPerPlayer)
                {
                    text = "#" + (i + 1).ToString();
                }
                else if (i == Game.TurnsPerPlayer)
                {
                    text = "Total";
                }
                else
                {
                    xOffset += 20;
                    text = "Score";
                }

                Utility.DrawTextCentered(g, text, Color.Yellow, yOffset, xOffset, 22);

                xOffset += 65; // Change the xOffset so we draw further left on the screen.
            }

            // Draw a bar under the column headings.
            g.FillRectangle(new SolidBrush(Color.Yellow), new Rectangle(10, 125, 480, 5));

            // Rows start lower then the column headings.
            yOffset += 70;

            // Draw each score row.
            for (int i = 0; i < Game.MaxPlayers; i++ )
            {
                if (game.GetActivity(i))
                {
                    DrawScoreRow(g, yOffset, i);
                    yOffset += 50;
                }
            }
        }

        /// <summary>
        /// Handles the key input.
        /// </summary>
        /// <param name="key">Key that was pressed.</param>
        public override void KeyPress(Keys key)
        {
            switch (key)
            {
                case Keys.Escape:
                    ToMainMenu();
                    break;

                case Keys.Enter:
                    NewGame();
                    break;
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Draw a row of the score table of a given player at a given yOffset.
        /// </summary>
        /// <param name="g">Graphics to be drawn on.</param>
        /// <param name="yOffset">YOffset to draw the row at.</param>
        /// <param name="player">The player to draw the score of.</param>
        private void DrawScoreRow(Graphics g, int yOffset, int player)
        {
            int xOffset = -210;
            double size;
            string score;


            for (int i = 0; i < Game.TurnsPerPlayer + 2; i++)
            {
                if (i < Game.TurnsPerPlayer)
                {
                    size = game.GetBlobPercentage(player, i);

                    // If the player didn't use this many blobs
                    if (size == -1)
                    {
                        score = "-"; // Use "-" to represent unused blobs.
                    }
                    else
                    {
                        score = (Math.Round(size * 1000)).ToString();
                    }
                }
                else if (i == Game.TurnsPerPlayer)
                {
                    // Second last column is for the total blob size.
                    score = (Math.Round(game.GetTotalPercentage(player) * 1000)).ToString();
                }
                else
                {
                    xOffset += 20;
                    // Last column is for the players current score.
                    score = game.GetScore(player).ToString();
                }

                Utility.DrawTextCentered(g, score, game.GetColor(player), yOffset, xOffset, 20);

                xOffset += 65;
            }
        }

        /// <summary>
        /// Reset the game variables and go to MapSelection.
        /// This method is called when you press "NEXT".
        /// </summary>
        private void NewGame()
        {
            Game.GetInstance().InitGameVariables();

            if (Game.RandomMap)
            {
                Game.GetInstance().SetMap(Map.NextRandom());
                InvalidateScreen(BlobSelectionScreen.GetInstance());
            }
            else
            {
                InvalidateScreen(MapSelectionScreen.GetInstance());
            }
        }

        /// <summary>
        /// Go back to the main menu.
        /// This method is called when you press "QUIT".
        /// </summary>
        private void ToMainMenu()
        {
            InvalidateScreen(MainMenuScreen.GetInstance());
        }

        #endregion
    }
}
